package com.tcppag.lengthbased;

import com.ByteBufUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;


/**
 * @author 罗俊华
 * @date 2021/8/27 - 10:35 上午
 */
@Slf4j
public class LengthBasedClient {

    public static void main(String[] args) {

        ChannelFuture channelFuture = new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline()
                                .addLast(new ChannelOutboundHandlerAdapter() {
                                    @Override
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                        log.debug("发送的数据包");
                                        ByteBufUtils.log((ByteBuf) msg);
                                        super.write(ctx, msg, promise);
                                    }
                                })
                               /* .addLast(new ChannelOutboundHandlerAdapter() {
                                    @Override
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

                                        ByteBuf byteBuf = (ByteBuf) msg;
                                        ByteBuf buf = ctx.alloc().buffer(byteBuf.capacity() + 2)
                                                .writeBytes(new byte[]{'h', '1'})
                                                .writeBytes(byteBuf);
                                        byteBuf.release();
                                        super.write(ctx, buf, promise);
                                    }
                                })*/
                                .addLast(
                                        new LengthFieldPrepender(4,true)
                                        /**
                                         * 这里长度调整的时候，lengthAdjustment = 4 和  lengthIncludesLengthFieldLength = true
                                         * 相当于在 length 基础上加了 4 并且 length 自身的长度也算在 length 里面，这里 length 自生的长度为4
                                         * 相当于在 length 的基础上 +8 作为 length
                                         * 等价于： new LengthFieldPrepender(ByteOrder.BIG_ENDIAN, 4, 8, false)
                                         * 等价于直接在length 上 +8 但是 lengthIncludesLengthFieldLength = false
                                         */
//                                        new LengthFieldPrepender(ByteOrder.BIG_ENDIAN, 4, 4, true)
                                )
                                /*.addLast(new ChannelOutboundHandlerAdapter() {
                                    @Override
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

                                        ByteBuf byteBuf = (ByteBuf) msg;
                                        ByteBuf buf = ctx.alloc().buffer(byteBuf.capacity() + 2)
                                                .writeBytes(new byte[]{'h', '2'})
                                                .writeBytes(byteBuf);
                                        byteBuf.release();
                                        super.write(ctx, buf, promise);
                                    }
                                })*/
                                .addLast(new StringEncoder(StandardCharsets.UTF_8));

                    }
                }).connect("localhost", 1090);

        channelFuture.addListener((ChannelFuture c) -> {
            Channel channel = c.channel();

            channel.write("你好，服务器");

            channel.write("收到响应了吗？");

            channel.write("今天天气怎么样？");

            /*channel.write("a");

            channel.write("bb");

            channel.write("ccc");*/


            channel.flush();

        });
    }
}
